﻿using SerialCommunication.Commands;
using SerialCommunication.Common.SerialPorts;
using SerialCommunication.Model;
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Windows;
using System.Windows.Input;

namespace SerialCommunication.ViewModel
{
    public class EnumItem
    {
        public string EnumName { get; set; }
        public object Value { get; set; }
    }

    public class SerialPortViewModel : SerialPortSetting
    {
        #region 参数
        /// <summary>
        /// 串口实例
        /// </summary>
        private readonly ScalesSerialPort _DefaultSerialPort = new ScalesSerialPort();
        private readonly ScalesSerialPort _warpperSerialPort = new ScalesSerialPort(new SerialPort());
        private readonly NotificationOjbect _notification = new NotificationOjbect();
        /// <summary>
        /// 静态串口实例是否打开
        /// </summary>
        private bool _WarpperSerialPortStaticInstanceIsOpen;
        #endregion

        #region 构造函数
        public SerialPortViewModel()
        {
            _btnWeight = "同步称重";
            _btnReadSerialPort = "读取串口数据...";

            this.PortName = SerialPortSetting.Instance.PortName;
            this.BaudRate = SerialPortSetting.Instance.BaudRate;
            this.DataBits = SerialPortSetting.Instance.DataBits;
            this.Parity = SerialPortSetting.Instance.Parity;
            this.StopBits = SerialPortSetting.Instance.StopBits;
            this.StartChar = SerialPortSetting.Instance.StartChar;
        }
        #endregion

        #region 初始化数据
        public List<EnumItem> EnumToList<T>()
        {
            return Enum.GetValues(typeof(T)).Cast<T>().Select(v => new EnumItem { EnumName = v.ToString(), Value = v }).ToList();
        }
        /// <summary>
        /// 串口名称
        /// </summary>
        /// <returns></returns>
        public List<string> PortNames
        {
            get
            {
                string[] spname = SerialPort.GetPortNames();
                if (spname.Length > 0)
                {
                    return spname.ToList();
                }
                return null;
            }
        }
        /// <summary>
        /// 波特率
        /// </summary>
        /// <returns></returns>
        public List<int> BaudRates
        {
            get
            {
                return new List<int>() { 1200, 9600 };
            }
        }
        /// <summary>
        /// 奇偶校验位
        /// </summary>
        /// <returns></returns>
        public List<EnumItem> GetParitys
        {
            get
            {
                return EnumToList<Parity>();
            }
        }
        /// <summary>
        /// 停止位数
        /// </summary>
        /// <returns></returns>
        public List<EnumItem> GetStopBits
        {
            get
            {
                return EnumToList<StopBits>().Select(item => new EnumItem() { EnumName = ((int)((StopBits)item.Value)).ToString(), Value = item.Value.ToString() }).ToList();
            }
        }
        #endregion

        #region 参数
        private string _btnReadSerialPort;
        /// <summary>
        /// 按钮名称
        /// </summary>
        public string btnReadSerialPort
        {
            get { return _btnReadSerialPort; }
            set
            {
                _btnReadSerialPort = value;
                _notification.RaisePropertyChanged("btnReadSerialPort");
            }
        }

        private string _txtDataReceive;
        /// <summary>
        /// 读取数据
        /// </summary>
        public string txtDataReceive
        {
            get { return _txtDataReceive; }
            set
            {
                _txtDataReceive = value;
                _notification.RaisePropertyChanged("txtDataReceive");
            }
        }

        private string _btnWeight;
        /// <summary>
        /// 读取数据
        /// </summary>
        public string btnWeight
        {
            get { return _btnWeight; }
            set
            {
                _btnWeight = value;
                _notification.RaisePropertyChanged("btnWeight");
            }
        }
        private string _txtWeight;
        /// <summary>
        /// 读取数据
        /// </summary>
        public string txtWeight
        {
            get { return _txtWeight; }
            set
            {
                _txtWeight = value;
                _notification.RaisePropertyChanged("txtWeight");
            }
        }
        #endregion

        /// <summary>
        /// 打开串口
        /// </summary>
        private bool OpenSerialPort()
        {
            try
            {
                if (_warpperSerialPort.IsOpen)
                    _warpperSerialPort.Close();

                if (_DefaultSerialPort.IsOpen && _DefaultSerialPort.PortName.Equals(this.PortName))
                {
                    _WarpperSerialPortStaticInstanceIsOpen = true;
                    _DefaultSerialPort.Close();
                }
                _warpperSerialPort.SetConfig(this);
                _warpperSerialPort.Open();
                return true;
            }
            catch (System.UnauthorizedAccessException)
            {
                MessageBox.Show("端口被可能其他程序占用。", "提示");
            }
            catch (Exception ex)
            {
                MessageBox.Show("打开端口时发生错误,端口不存在或电子称未连接：" + ex.Message, "提示");
            }
            return false;
        }

        private void btnReadSerialPort_Click(object param)
        {
            if (!OpenSerialPort()) return;
            if (btnReadSerialPort.Equals("读取串口数据..."))
            {
                txtDataReceive = string.Empty;
                _warpperSerialPort.orginDataReceived += _serialPort_DataReceived;
                btnReadSerialPort = "停止读取数据...";
            }
            else
            {
                _warpperSerialPort.orginDataReceived -= _serialPort_DataReceived;
                btnReadSerialPort = "读取串口数据...";
            }
        }

        private void _serialPort_DataReceived(string orginData)
        {
            txtDataReceive += orginData + "\r\n";
        }

        private void btnWeight_Click(object param)
        {
            if (!OpenSerialPort()) return;
            if (btnWeight.Equals("同步称重"))
            {
                _warpperSerialPort.resultReceived += WeightReceived;
                btnWeight = "停止称重";
            }
            else
            {
                _warpperSerialPort.resultReceived -= WeightReceived;
                btnWeight = "同步称重";
            }
        }

        private void WeightReceived(string StrWeight)
        {
            txtWeight = StrWeight;
        }

        private void btnSave_Click(object param)
        {
            if (!OpenSerialPort()) return;
            SerialPortSetting.Instance.PortName = this.PortName;
            SerialPortSetting.Instance.BaudRate = this.BaudRate;
            SerialPortSetting.Instance.DataBits = this.DataBits;
            SerialPortSetting.Instance.Parity = this.Parity;
            SerialPortSetting.Instance.StopBits = this.StopBits;
            SerialPortSetting.Instance.StartChar = this.StartChar;
            SerialPortSetting.Instance.Save();

            if (_warpperSerialPort.IsOpen) _warpperSerialPort.Close();
            if (_WarpperSerialPortStaticInstanceIsOpen) _DefaultSerialPort.Open();

            _DefaultSerialPort.SetConfig(this);
            MessageBox.Show("保存成功！", "提示");
        }

        public ICommand ReadSerialPort
        {
            get
            {
                return new DelegateCommand(
                    (param) =>
                    {
                        btnReadSerialPort_Click(param);
                    }
                   , (v) => { return true; });
            }
        }
        public ICommand ReadWeight
        {
            get
            {
                return new DelegateCommand(
                    (param) =>
                    {
                        btnWeight_Click(param);
                    }
                   , (v) => { return true; });
            }
        }

        public ICommand SaveSerialPort
        {
            get
            {
                return new DelegateCommand(
                    (param) =>
                    {
                        btnSave_Click(param);
                    }
                   , (v) => { return true; });
            }
        }
    }
}
